expression: Invalidate bindings before destroying them
authorBenjamin Otte <otte@redhat.com>
Tue, 26 Nov 2019 02:57:40 +0000 (03:57 +0100)
committerMatthias Clasen <mclasen@redhat.com>
Sat, 30 May 2020 21:48:44 +0000 (17:48 -0400)
Use a weak ref to invalidate bindings. Make sure that this happens
before creating any watches, so that notifies from the
watched expression about changes will not trigger set_property() calls
during dispose()/finalize().

Invalidating also ensures that the watches aren't removed, which can
trigger warnings if the watches are watching the object itself, and the
weak refs cannot be removed anymore.

gtk/gtkexpression.c

index dfa65e251ecb627fabd01d49e21061f1f99136d3..c698f8038ed790aa6523444aa54b5ec727439d50 100644 (file)
@@ -1292,6 +1292,21 @@ typedef struct {
   GParamSpec *pspec;
 } GtkExpressionBind;
 
+static void
+invalidate_binds (gpointer unused,
+                  GObject *object)
+{
+  GSList *l, *binds;
+
+  binds = g_object_get_data (object, "gtk-expression-binds");
+  for (l = binds; l; l = l->next)
+    {
+      GtkExpressionBind *bind = l->data;
+
+      bind->object = NULL;
+    }
+}
+
 static void
 free_binds (gpointer data)
 {
@@ -1319,6 +1334,8 @@ gtk_expression_bind_free (gpointer data)
       binds = g_slist_remove (binds, bind);
       if (binds)
         g_object_set_data_full (bind->object, "gtk-expression-binds", binds, free_binds);
+      else
+        g_object_weak_unref (bind->object, invalidate_binds, NULL);
     }
   gtk_expression_unref (bind->expression);
 
@@ -1331,6 +1348,9 @@ gtk_expression_bind_notify (gpointer data)
   GValue value = G_VALUE_INIT;
   GtkExpressionBind *bind = data;
 
+  if (bind->object == NULL)
+    return;
+
   if (!gtk_expression_evaluate (bind->expression, bind->object, &value))
     return;
 
@@ -1386,6 +1406,9 @@ gtk_expression_bind (GtkExpression *self,
     }
 
   bind = g_slice_new0 (GtkExpressionBind);
+  binds = g_object_steal_data (object, "gtk-expression-binds");
+  if (binds == NULL)
+    g_object_weak_ref (object, invalidate_binds, NULL);
   bind->expression = self;
   bind->object = object;
   bind->pspec = pspec;
@@ -1394,7 +1417,6 @@ gtk_expression_bind (GtkExpression *self,
                                       gtk_expression_bind_notify,
                                       bind,
                                       gtk_expression_bind_free);
-  binds = g_object_steal_data (object, "gtk-expression-binds");
   binds = g_slist_prepend (binds, bind);
   g_object_set_data_full (object, "gtk-expression-binds", binds, free_binds);